module ctrl(
    input clk,
    input reset,
    input except_ena,
    input [63:0] mtvec_pc,
    input [63:0] epc,
    input ret,
    input stall_from_if,
    input stall_from_mem,
    input inst_r_valid,
    input mtime_int,
    input [63:0] mstatus,
    input [63:0] mie,
    
    output reg [63:0] new_pc,
    output reg flush,
    output reg [5:0] stall,
    output reg keep
);

    always @(posedge clk) begin
        if(except_ena || ret || mtime_int && mstatus[3] == 1'b1 && mie[7] == 1'b1) begin
            keep <= 1'b1;
        end
        if(keep == 1'b1 && inst_r_valid == 1'b1) begin
            keep <= 1'b0;
        end
    end

    always @(*) begin
        if(reset) begin
            stall = 6'b000000;
            flush = 1'b0;
            new_pc = 64'd0;
        end else if((except_ena || mtime_int) && mstatus[3] == 1'b1 && mie[7] == 1'b1) begin
            new_pc = mtvec_pc;
            stall = 6'b000000;
            flush = 1'b1;
        end else if(ret) begin
            new_pc = epc;
            flush = 1'b1;
            stall = 6'b000000;
        end else if(stall_from_mem) begin
            new_pc = 64'd0;
            flush = 1'b0;
            stall = 6'b011111;
        end else if(stall_from_if) begin
            new_pc = 64'd0;
            flush = 1'b0;
            stall = 6'b000111;
        end else begin
            stall = 6'b000000;
            flush = 1'b0;
            new_pc = 64'd0;
        end
    end
    
endmodule